package com.ayf.payment.game.api.service.impl;

import com.ayf.payment.game.api.channel.alipay.service.AliPayService;
import com.ayf.payment.game.api.dto.GamePlayerCashOrderDTO;
import com.ayf.payment.game.api.dto.MerchantDTO;
import com.ayf.payment.game.api.dto.SumGamePlayerCashOrderDTO;
import com.ayf.payment.game.api.dto.UpdateGamePlayerCashOrderDTO;
import com.ayf.payment.game.api.dto.alipay.AliOrderStatus;
import com.ayf.payment.game.api.dto.alipay.MerchantAlipayOrderDTO;
import com.ayf.payment.game.api.dto.criteria.GameOrderCriteria;
import com.ayf.payment.game.api.dto.criteria.GameOrderPageCriteria;
import com.ayf.payment.game.api.dto.criteria.GamePlayerCashOrderStatisticsCriteria;
import com.ayf.payment.game.api.dto.response.GamePlayerCashOrderStatisticsDTO;
import com.ayf.payment.game.api.entity.GamePlayerCashOrder;
import com.ayf.payment.game.api.entity.Merchant;
import com.ayf.payment.game.api.gateway.GatewayUtil;
import com.ayf.payment.game.api.mapper.GamePlayerCashOrderMapper;
import com.ayf.payment.game.api.service.GamePlayerCashOrderService;
import com.ayf.payment.game.api.service.GamePlayerGatewayConfigService;
import com.ayf.payment.game.api.service.MerchantAlipayOrderService;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.utils.DateUtils;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class GamePlayerCashOrderServiceImpl implements GamePlayerCashOrderService {

    @Resource
    private GamePlayerCashOrderMapper gamePlayerCashOrderMapper;

    @Autowired
    private MerchantAlipayOrderService merchantAlipayOrderService;
    @Autowired
    private AliPayService aliPayService;
    @Autowired
    private GamePlayerGatewayConfigService gamePlayerGatewayConfigService;
    @Autowired
    private MerchantService merchantService;

    @Override
    public void updateById(UpdateGamePlayerCashOrderDTO dto) {
        GamePlayerCashOrder convert = BeanConvertUtils.convert(dto, GamePlayerCashOrder.class);
        gamePlayerCashOrderMapper.updateByPrimaryKeySelective(convert);
    }


    @Override
    public void updateById(GamePlayerCashOrderDTO dto) {
        GamePlayerCashOrder select = this.gamePlayerCashOrderMapper.selectByPrimaryKey(dto.getId());
        GamePlayerCashOrder convert = BeanConvertUtils.convert(dto, GamePlayerCashOrder.class);
        convert.setId(select.getId());
        gamePlayerCashOrderMapper.updateByPrimaryKeySelective(convert);
        dto.setId(convert.getId());
        dto.setGameOrderNo(select.getGameOrderNo());
        dto.setRequestIp(select.getRequestIp());
        dto.setMerchantId(select.getMerchantId());
        dto.setNotifyUrl(select.getNotifyUrl());
        playerGatewayNotify(dto);
    }

    @Override
    public void updateByMerChantOrderNo(GamePlayerCashOrderDTO dto) {
        GamePlayerCashOrder gamePlayerCashOrder = new GamePlayerCashOrder();
        gamePlayerCashOrder.setMerchantOrderNo(dto.getMerchantOrderNo());
        GamePlayerCashOrder select = gamePlayerCashOrderMapper.selectOne(gamePlayerCashOrder);
        GamePlayerCashOrder convert = BeanConvertUtils.convert(dto, GamePlayerCashOrder.class);
        convert.setId(select.getId());
        gamePlayerCashOrderMapper.updateByPrimaryKeySelective(convert);
        dto.setId(convert.getId());
        dto.setGameOrderNo(select.getGameOrderNo());
        dto.setRequestIp(select.getRequestIp());
        dto.setMerchantId(select.getMerchantId());
        dto.setNotifyUrl(select.getNotifyUrl());
        playerGatewayNotify(dto);
    }

    public void updateIsNotifySuccess(String id, Integer isNotifySuccess) {
        GamePlayerCashOrder convert = new GamePlayerCashOrder();
        convert.setId(id);
        convert.setIsNotifySuccess(isNotifySuccess);
        gamePlayerCashOrderMapper.updateByPrimaryKeySelective(convert);
    }

    @Override
    public void playerGatewayNotify(GamePlayerCashOrderDTO dto) {
        if (dto.getStatus() == null || !dto.getStatus().equals(AliOrderStatus.SUCCESS.getCode())) {
            return;
        }
        LogPortal.info("玩家提现通知游戏网关开始执行。商户订单号：{}，游戏订单号：{}", dto.getMerchantOrderNo(), dto.getGameOrderNo());
        if (StringUtils.isEmpty(dto.getNotifyUrl())) {
            LogPortal.error("玩家提现通知游戏网关失败，NotifyUrl为空。商户订单号：{}，游戏订单号：{}", dto.getMerchantOrderNo(), dto.getGameOrderNo());
            return;
        }
        Merchant merchant = new Merchant();
        merchant.setId(dto.getMerchantId());
        MerchantDTO merchantDTO = merchantService.selectOne(merchant);
        boolean bo = GatewayUtil.playerGatewayNotify(dto.getMerchantOrderNo(), dto.getGameOrderNo(), merchantDTO.getPrivateKey(), dto.getNotifyUrl());
        if (bo) {
            updateIsNotifySuccess(dto.getId(), 1);
        } else {
            updateIsNotifySuccess(dto.getId(), 2);
        }
    }

    @Override
    public List<GamePlayerCashOrderDTO> listexport(GameOrderCriteria criteria) {
        if (StringUtils.isNotBlank(criteria.getStartTime())) {
            Date date = DateUtils.stringToDate(criteria.getStartTime());
            criteria.setStartDataIndex(DateUtils.dateToInteger(date));
        }
        if (StringUtils.isNotBlank(criteria.getEndTime())) {
            Date date = DateUtils.stringToDate(criteria.getEndTime());
            criteria.setEndDataIndex(DateUtils.dateToInteger(date));
        }
        return gamePlayerCashOrderMapper.listexport(criteria);
    }

    @Override
    public GamePlayerCashOrderStatisticsDTO dayStatisticsList(GamePlayerCashOrderStatisticsCriteria criteria) {
        GamePlayerCashOrderStatisticsDTO gamePlayerCashOrderStatisticsDTO = gamePlayerCashOrderMapper.dayStatisticsSum(criteria);
        List<GamePlayerCashOrderStatisticsDTO> gamePlayerCashOrderStatisticsDTOList = gamePlayerCashOrderMapper.dayStatisticsList(criteria);
        if (!CollectionUtils.isEmpty(gamePlayerCashOrderStatisticsDTOList)){
            gamePlayerCashOrderStatisticsDTOList.forEach(item->{
                String applyTimeIndexStr = String.valueOf(item.getApplyTimeIndex());
                item.setApplyTimeIndexStr(applyTimeIndexStr.substring(0,4).concat("-").concat(applyTimeIndexStr.substring(4,6).concat("-")).concat(applyTimeIndexStr.substring(6,8)));
            });
        }
        gamePlayerCashOrderStatisticsDTO.setList(gamePlayerCashOrderStatisticsDTOList);
        return gamePlayerCashOrderStatisticsDTO;
    }

    /**
     * 根据商户订单号更新状态
     * @author lch
     * @date 2021/12/13
     */
    @Override
    public void updateStatusByMerChantOrderNo(GamePlayerCashOrderDTO dto) {
        Example example = new Example(GamePlayerCashOrder.class);
        example.createCriteria().andEqualTo(GamePlayerCashOrder.Fields.merchantOrderNo, dto.getMerchantOrderNo());
        GamePlayerCashOrder select = gamePlayerCashOrderMapper.selectOneByExample(example);

        GamePlayerCashOrder convert = BeanConvertUtils.convert(dto, GamePlayerCashOrder.class);
        convert.setId(select.getId());
        gamePlayerCashOrderMapper.updateByPrimaryKeySelective(convert);
    }


    @Override
    public List<GamePlayerCashOrderDTO> list(GameOrderPageCriteria criteria) {
        if (StringUtils.isNotBlank(criteria.getStartTime())) {
            Date date = DateUtils.stringToDate(criteria.getStartTime());
            criteria.setStartDataIndex(DateUtils.dateToInteger(date));
        }
        if (StringUtils.isNotBlank(criteria.getEndTime())) {
            Date date = DateUtils.stringToDate(criteria.getEndTime());
            criteria.setEndDataIndex(DateUtils.dateToInteger(date));
        }
        return gamePlayerCashOrderMapper.list(criteria);
    }

    @Override
    public void addAliPayOrder(GamePlayerCashOrderDTO dto1, String traceId) {
        MerchantAlipayOrderDTO dto = BeanConvertUtils.convert(dto1, MerchantAlipayOrderDTO.class);
        Map<String, Object> map = aliPayService.balanceQuery(traceId, dto.getMerchantId(), dto.getMerchantOrderNo());
        BigDecimal balance = (BigDecimal) map.get("balance");
        if ("1".equals(map.get("status").toString())) {
            if (dto.getTransAmount().compareTo(balance) > 0) {
                dto1.setStatus(AliOrderStatus.FAIL.getCode());
                dto1.setFailReason("支付宝账号余额不足，余额为：" + balance + "元");
                updateByMerChantOrderNo(dto1);
            } else {
                dto.setOrderSource(2);
                dto.setId(null);
                merchantAlipayOrderService.save(dto);
                aliPayService.orderCreate(dto);
            }
        } else {
            dto1.setStatus(AliOrderStatus.FAIL.getCode());
            dto1.setFailReason(map.get("msg") + "");
            updateByMerChantOrderNo(dto1);
        }
    }

    @Override
    public void delGameOrder(GameOrderCriteria criteria) {
        gamePlayerCashOrderMapper.delByList(criteria);
    }

    @Override
    public void addGameOrder(GamePlayerCashOrderDTO orderDTO) {
        GamePlayerCashOrder convert = BeanConvertUtils.convert(orderDTO, GamePlayerCashOrder.class);
        gamePlayerCashOrderMapper.insertSelective(convert);
    }

    @Override
    public SumGamePlayerCashOrderDTO sum(GameOrderCriteria criteria) {
        return gamePlayerCashOrderMapper.getSum(criteria);
    }

    @Override
    public GamePlayerCashOrderDTO findByGameOrderNo(Integer merchantId, String gameOrderNo) {
        GamePlayerCashOrder gamePlayerCashOrder = new GamePlayerCashOrder();
        gamePlayerCashOrder.setMerchantId(merchantId);
        gamePlayerCashOrder.setGameOrderNo(gameOrderNo);
        GamePlayerCashOrder temp = gamePlayerCashOrderMapper.selectOne(gamePlayerCashOrder);
        return BeanConvertUtils.convert(temp, GamePlayerCashOrderDTO.class);
    }

    @Override
    public GamePlayerCashOrder findById(String id) {
        return gamePlayerCashOrderMapper.selectByPrimaryKey(id);
    }
}
